package com.ruiysoft.crm.controller;

import com.alibaba.fastjson.JSON;
import com.ruiysoft.crm.dto.OrderEx;
import com.ruiysoft.crm.entity.EmployeeCourse;
import com.ruiysoft.crm.entity.OrderProgress;
import com.ruiysoft.crm.entity.SysLog;
import com.ruiysoft.crm.mapper.EmployeeCourseMapper;
import com.ruiysoft.crm.mapper.OrderMapper;
import com.ruiysoft.crm.mapper.OrderProgressMapper;
import com.ruiysoft.crm.mapper.SysLogMapper;
import org.apache.commons.lang.StringUtils;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.security.MessageDigest;
import java.util.*;


/**
 * Created by liudh on 2017/3/4.
 */

@RestController
@RequestMapping("payment")
public class WeixinPayController {
    @Autowired
    SysLogMapper sysLogMapper;

    int writeLog2Db(Integer who, String ...data) {
        SysLog sysLog = new SysLog();
        sysLog.setCreateTime(new Date());

        if(data.length > 0)
            sysLog.setData1(data[0]);
        if(data.length > 1)
            sysLog.setData2(data[1]);
        if(data.length > 2)
            sysLog.setData3(data[2]);
        if(data.length > 3)
            sysLog.setData4(data[3]);
        if(data.length > 4)
            sysLog.setData5(data[4]);
        if(data.length > 5)
            sysLog.setData6(data[5]);
        if(data.length > 6)
            sysLog.setData7(data[6]);
        if(data.length > 7)
            sysLog.setData8(data[7]);
        if(data.length > 8)
            sysLog.setData9(data[8]);

        if(sysLogMapper.insert(sysLog) > 0)
            return 0;
        else
            return -1;
    }

    HttpHelper httpClient = new HttpHelper();

    @Value("${weixin.appId}")
    String _appId = "";

    @Value("${weixin.payKey}")
    String _payKey = "";

    @Value("${weixin.mch_id}")
    String _mch_id = "";

    @Value("${weixin.notify_url}")
    String _notify_url = "";

    String getChildrenText(List children) {
        StringBuffer sb = new StringBuffer();
        if(!children.isEmpty()) {
            Iterator it = children.iterator();
            while(it.hasNext()) {
                Element e = (Element) it.next();
                String name = e.getName();
                String value = e.getTextNormalize();
                List list = e.getChildren();
                sb.append("<" + name + ">");
                if(!list.isEmpty()) {
                    sb.append(getChildrenText(list));
                }
                sb.append(value);
                sb.append("</" + name + ">");
            }
        }

        return sb.toString();
    }

    Map doXMLParse(String strxml) throws JDOMException, IOException {
        strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");

        if(null == strxml || "".equals(strxml)) {
            return null;
        }

        Map m = new HashMap();

        InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));
        SAXBuilder builder = new SAXBuilder();
        Document doc = builder.build(in);
        Element root = doc.getRootElement();
        List list = root.getChildren();
        Iterator it = list.iterator();
        while(it.hasNext()) {
            Element e = (Element) it.next();
            String k = e.getName();
            String v = "";
            List children = e.getChildren();
            if(children.isEmpty()) {
                v = e.getTextNormalize();
            } else {
                v = getChildrenText(children);
            }

            m.put(k, v);
        }

        in.close();

        return m;
    }

//    String md5(String in) {
//        try {
//            // 生成一个MD5加密计算摘要
//            MessageDigest md = MessageDigest.getInstance("MD5");
//            // 计算md5函数
//            md.update(in.getBytes());
//            // digest()最后确定返回md5 hash值，返回值为8为字符串。因为md5 hash值是16位的hex值，实际上就是8位的字符
//            // BigInteger函数则将8位的字符串转换成16位hex值，用字符串来表示；得到字符串形式的hash值
//            return new BigInteger(1, md.digest()).toString(16);
//
//        } catch (Exception e) {
//            ;
//        }
//
//        return "error";
//    }

    String md52(String in) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] array = md.digest(in.getBytes("UTF-8"));
            StringBuilder sb = new StringBuilder();
            for (byte item : array) {
                sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
            }

            return sb.toString().toUpperCase();
        } catch (Exception e) {
            ;
        }

        return "";
    }

//    void returnJson(HttpServletResponse response, Map map) {
//        String jSon = JSON.toJSONString(map);
//        response.setCharacterEncoding("utf-8");
//        response.addHeader("Access-Control-Allow-Origin","*");
//
//        try {
//            response.getWriter().write(jSon);
//
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//    }

//    @RequestMapping(value = "/getPrepayId")
//    @ResponseBody
    @GetMapping("getPrepayId")
    String getPrepayId(String body, String out_trade_no, String total_fee, String openid) {
        String prepayId = "";
        SortedMap<Object, Object> map = new TreeMap<Object, Object>();

        map.put("appid", _appId);
        map.put("mch_id", _mch_id);
        map.put("nonce_str", UUID.randomUUID().toString().replace("-", "").substring(0, 16));
        map.put("body", body);
        System.out.println("body: " + map.get("body"));

//        String out_trade_no = "";
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
//        out_trade_no += sdf.format(new Date());
//        out_trade_no += "" + (int)(100 + Math.random() * (999 - 100 + 1));
//        map.put("out_trade_no", out_trade_no);
        map.put("out_trade_no", out_trade_no);
        System.out.println("out_trade_no: " + map.get("out_trade_no"));

        map.put("total_fee", total_fee);
        System.out.println("total_fee: " + map.get("total_fee"));

        map.put("spbill_create_ip", "127.0.0.1");
        map.put("notify_url", _notify_url);
        map.put("trade_type", "JSAPI");

        map.put("openid", openid);
        System.out.println("openid: " + map.get("openid"));

        StringBuffer sb = new StringBuffer();

        Set es = map.entrySet();
        Iterator it = es.iterator();
        while(it.hasNext()) {
            Map.Entry entry = (Map.Entry)it.next();
            String k = (String)entry.getKey();
            Object v = entry.getValue();
            if(null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }

        sb.append("key=" + _payKey);

        System.out.println("sing input: " + sb.toString());
        String sign = md52(sb.toString()).toUpperCase();
        System.out.println("sign: " + sign);
        System.out.println("sign length: " + sign.length());
        map.put("sign", sign);

        sb = new StringBuffer();
        sb.append("<xml>");
        es = map.entrySet();
        it = es.iterator();
        while(it.hasNext()) {
            Map.Entry entry = (Map.Entry)it.next();
            String k = (String)entry.getKey();
            String v = (String)entry.getValue();
            if ("attach".equalsIgnoreCase(k)||"body".equalsIgnoreCase(k)||"sign".equalsIgnoreCase(k)) {
                sb.append("<"+k+">"+"<![CDATA["+v+"]]></"+k+">");
            }else {
                sb.append("<"+k+">"+v+"</"+k+">");
            }
        }
        sb.append("</xml>");

        System.out.println("xml: " + sb.toString());

        try {
            writeLog2Db(null, "请求prepay_id, 发送", sb.toString());
            String rtn = httpClient.postData("https://api.mch.weixin.qq.com/pay/unifiedorder", sb.toString());
            writeLog2Db(null, "请求prepay_id, 返回", rtn);

            Map mapRtn = doXMLParse(rtn);
            if(mapRtn != null) {
                if(mapRtn.get("result_code") != null && mapRtn.get("result_code").equals("FAIL")
                        || mapRtn.get("return_code") != null && mapRtn.get("return_code").equals("FAIL")) {
                    prepayId = "error, " + mapRtn.get("err_code_des") + ", " + mapRtn.get("return_msg");
                    System.out.println("error, prepayId: " + prepayId);

                } else  {
                    prepayId = mapRtn.get("prepay_id") + "";
                    System.out.println("prepayId: " + prepayId);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return prepayId;
    }

    String createSign(String characterEncoding,SortedMap<Object,Object> parameters){
        StringBuffer sb = new StringBuffer();
        Set es = parameters.entrySet();
        Iterator it = es.iterator();
        while(it.hasNext()) {
            Map.Entry entry = (Map.Entry)it.next();
            String k = (String)entry.getKey();
            Object v = entry.getValue();
            if(null != v && !"".equals(v)
                    && !"sign".equals(k) && !"key".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key=" + _payKey);
        String sign = md52(sb.toString()).toUpperCase();
        return sign;
    }

    @GetMapping("getPaySign")
    public Object getPaySign(HttpServletRequest request, HttpServletResponse response) {
        Map out = new HashMap();
        out.put("success", false);

        // "1395712654"
//        String timeStamp = request.getParameter("timeStamp");
        String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
//        String nonceStr = "lsrlyy";

        String body = request.getParameter("body");
        String out_trade_no = request.getParameter("out_trade_no");
        String total_fee = request.getParameter("total_fee");

        String openid = request.getParameter("openid");
        // 网关会把openid塞到header中
//        String openid = request.getHeader("openid");
        System.out.println("从header获取openid: " + openid);
        // "prepay_id=wx201703050214240af32d732d0338414584"

        /*
        body: 平安短期境内旅游保险(经济型)
        out_trade_no: 15024468034680051545416
        total_fee: 1
        openid: oFT0JwrarlVz0J-3ULeEXyV_XfJE
        error, prepayId: error, null, sign参数长度有误
         */
        String prepay_id = getPrepayId(body, out_trade_no, total_fee, openid);

        if(prepay_id.startsWith("error"))
            out.put("errorMsg", prepay_id);
        else {
            String signType = "MD5";
            SortedMap<Object, Object> payparams = new TreeMap<Object, Object>();
            payparams.put("appId", _appId);
            payparams.put("timeStamp", timeStamp);
            payparams.put("nonceStr", "lsrlyy");

            payparams.put("package", "prepay_id=" + prepay_id);
            System.out.println("package: " + payparams.get("package"));

            payparams.put("signType", "MD5");
            String paySign = createSign("UTF-8", payparams);
            writeLog2Db(null, "微信支付签名", paySign);

            out.put("success", true);
            out.put("sign", paySign);
            out.put("prepay_id", prepay_id);
            out.put("timeStamp", timeStamp);
            out.put("data", payparams);

            System.out.println("paySign: " + paySign);
        }

        return out;
    }

    @Autowired
    EmployeeCourseMapper employeeCourseMapper;

    @Autowired
    OrderMapper orderMapper;

    @Autowired
    OrderProgressMapper orderProgressMapper;

    boolean writeEmployeeCourse(String orderNu) {
        System.out.println("orderNu: " + orderNu);

        OrderEx orderEx = orderMapper.selectLeftJoinOrderDetail(orderNu);
        if(orderEx != null) {
            System.out.println("orderEx: " + JSON.toJSONString(orderEx));

            EmployeeCourse employeeCourse = new EmployeeCourse();
            employeeCourse.setEmployeeId(orderEx.getEmployeeId());
            employeeCourse.setCourseId(orderEx.getMerchandiseId());

            if(employeeCourseMapper.insert(employeeCourse) > 0) {
                orderEx.setStatus("courseStatus_02");
                orderEx.setUpdateTime(new Date());

                if(orderMapper.updateById(orderEx) > 0) {
                    writeLog2Db(null, "支付成功，更新订单", JSON.toJSONString(employeeCourse));

                    OrderProgress orderProgress = new OrderProgress();
                    orderProgress.setOrderId(orderEx.getId());
                    orderProgress.setType("2");
                    orderProgress.setCreateTime(new Date());

                    if(orderProgressMapper.insert(orderProgress) > 0)
                        return true;
                }
            }

        }

        return false;
    }

    @PostMapping("receiveCallBack")
    public void receiveCallBack(HttpServletRequest request, HttpServletResponse response) {
        String msgXml = "";
        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(request.getInputStream(), "utf-8"));
            String rtn = br.readLine();
            while (rtn != null) {
                msgXml += rtn;
                rtn = br.readLine();
            }

//            if(!msgXml.equals("")) {
//                String returnXml = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
//                response.getWriter().write(returnXml);
//                System.out.println("已发送应答: " + returnXml);
//            }
            System.out.println("微信回调: " + msgXml);

            writeLog2Db(null, "微信回调", msgXml);

            Map result = doXMLParse(msgXml);
            if("SUCCESS".equals(result.get("return_code"))){
                Map<String,String>  param = new HashMap<String, String>();
                param.put("orderno",result.get("out_trade_no").toString());
                param.put("flag",result.get("result_code").toString());

//                rabbitTemplate.convertAndSend(exchange, routingKey1, JSON.toJSONString(param));
//                rabbitTemplate.convertAndSend(exchange, routingKey2, JSON.toJSONString(param));
//                rabbitTemplate.convertAndSend(exchange, routingKey3, msgXml);

                String orderNu = result.get("out_trade_no").toString();
                if(writeEmployeeCourse(orderNu))
                    System.out.println("支付成功");
                else
                    System.out.println("支付失败");


                //异步回调接口
                String returnXml = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
                response.getWriter().write(returnXml);
                System.out.println("已发送应答: " + returnXml);

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Autowired
    RedisTemplate redisTemplate;

    @GetMapping(value = "/testRedis")
    public Object testRedis(HttpServletRequest request, HttpServletResponse response) {
//        redisTemplate.opsForValue().set("abc", "123456");
//
//        Map map = new HashMap();
//        map.put("data", redisTemplate.opsForValue().get("abc"));
//
//        return map;
        writeEmployeeCourse("f3d2bd3c067940a9b2304b58a1ac54c2");

        return null;
    }

    // 退款
    @GetMapping("/refund")
    public String refund(String orderNo, String refundNo, String total_fee, String refund_fee) {
        Map<String, Object> outMap = new HashMap<String, Object>();
        outMap.put("success", false);

        SortedMap<Object, Object> map = new TreeMap<Object, Object>();

        map.put("appid", _appId);
        map.put("mch_id", _mch_id);
        map.put("out_trade_no", orderNo);
        map.put("out_refund_no", "tk_" + orderNo + "_" + refundNo);
        map.put("total_fee", total_fee);
        map.put("refund_fee", refund_fee);
        map.put("nonce_str", UUID.randomUUID().toString().replace("-", ""));

        StringBuffer sb = new StringBuffer();
        Set es = map.entrySet();
        Iterator it = es.iterator();
        while(it.hasNext()) {
            Map.Entry entry = (Map.Entry)it.next();
            String k = (String)entry.getKey();
            Object v = entry.getValue();
            if(null != v && !"".equals(v)
                    && !"sign".equals(k) && !"key".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key=" + _payKey);

        String sign = md52(sb.toString()).toUpperCase();
        map.put("sign", sign);

        sb = new StringBuffer();
        sb.append("<xml>");
        es = map.entrySet();
        it = es.iterator();
        while(it.hasNext()) {
            Map.Entry entry = (Map.Entry)it.next();
            String k = (String)entry.getKey();
            String v = (String)entry.getValue();
            if ("attach".equalsIgnoreCase(k)||"body".equalsIgnoreCase(k)||"sign".equalsIgnoreCase(k)) {
                sb.append("<"+k+">"+"<![CDATA["+v+"]]></"+k+">");
            }else {
                sb.append("<"+k+">"+v+"</"+k+">");
            }
        }
        sb.append("</xml>");

        System.out.println("xml: " + sb.toString());

        try {
            String rtn = httpClient.httpsSSLPostData("https://api.mch.weixin.qq.com/secapi/pay/refund", sb.toString());
            Map mapRtn = doXMLParse(rtn);
            String return_code = mapRtn.get("return_code") + "";

            System.out.println("return_code: " + return_code);
            if("SUCCESS".equals(return_code)) {
                outMap.put("success", true);
                outMap.put("data", mapRtn);
                System.out.println("success, true");
            }


        } catch (Exception e) {
            e.printStackTrace();
        }

        return JSON.toJSONString(outMap);
    }

//    @Autowired
//    RabbitTemplate rabbitTemplate;

    String exchange = "中佳保险";
    String routingKey1 = "微信支付成功-出单";
    String routingKey2 = "微信支付成功-更新订单";
    String routingKey3 = "微信支付成功-记日志";
    String routingKey4 = "核心系统-同步保单";

    @GetMapping("/testRabbitmq")
    public String testRabbitmq(HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> outMap = new HashMap<String, Object>();
        outMap.put("success", false);

//        String testData = "<xml><appid><![CDATA[wx7a4399adc02554cc]]></appid><bank_type><![CDATA[CFT]]></bank_type><cash_fee><![CDATA[1]]></cash_fee><fee_type><![CDATA[CNY]]></fee_type><is_subscribe><![CDATA[Y]]></is_subscribe><mch_id><![CDATA[1371893102]]></mch_id><nonce_str><![CDATA[lsrlyy]]></nonce_str><openid><![CDATA[oFT0JwlV4WcKKVgYI-E5xrm92LK0]]></openid><out_trade_no><![CDATA[10036]]></out_trade_no><result_code><![CDATA[SUCCESS]]></result_code><return_code><![CDATA[SUCCESS]]></return_code><sign><![CDATA[758C94B2E7C0B94045E20011DEBEE42F]]></sign><time_end><![CDATA[20170810111429]]></time_end><total_fee>1</total_fee><trade_type><![CDATA[JSAPI]]></trade_type><transaction_id><![CDATA[4000602001201708105453039783]]></transaction_id></xml>";
        String testData = "{\t\n" +
                "\t\"clientInfo\":{\n" +
                "\t\t\"name\":\"测试\",\n" +
                "        \"idNo\":\"14043119950228212X\",\n" +
                "        \"mobileNo\":\"13333333333\"  \n" +
                "    },\n" +
                "   \"insuredInfo\":{\n" +
                "\t\t\"name\":\"测试\",\n" +
                "        \"idNo\":\"14043119950228212X\",\n" +
                "        \"mobileNo\":\"13333333333\"  \n" +
                "    },\n" +
                "    \"bizpolicy\":{\n" +
                "        \"policyNo\":\"123456789\",\n" +
                "        \"insurerName\":\"中国平安北京分公司\",\n" +
                "        \"productName\":\"交强险\",\n" +
                "        \"billDate\":\"2015-12-26 13:57:56\",\n" +
                "        \"insBeginDate\":\"2015-12-26 13:57:56\",\n" +
                "        \"insEndDate\":\"2015-12-26 13:57:56\",\n" +
                "        \"insuredAmount\":\"100000\",\n" +
                "        \"permium\":\"25.02\",\n" +
                "        \"premiumStatus\":\"unliquidated\",\n" +
                "        \"commissonStats\":\"unliquidated\",\n" +
                "        \"accAgentName\":\"闫妍\",\n" +
                "\t\t\"accAgentId\":\"14781378018010014806384\",\n" +
                "        \"chudyName\":\"福运通002\",\n" +
                "\t\t\"chudyId\":\"14785844590540000050368\",\n" +
                "\t\t\"partnerName\":\"中泰万豪\",\n" +
                "        \"partnerName\":\"14785854234760020692910\",\n" +
                "\t\t\"carNo\":\"京A66666\",\n" +
                "        \"engineNumber\":\"E32L1700348\",\n" +
                "        \"firstRegistrationDate\":\"2015-01-01\",\n" +
                "        \"carsType\":\"普通货车\",\n" +
                "        \"carmodel\":\"BJ2037Y3MDV\",\n" +
                "        \"rateconfigbusinesslicensetype\":\"营运\",\n" +
                "        \"carWeight\":\"1.5\",\n" +
                "        \"displacement\":\"2.0\",\n" +
                "        \"seating\":\"5\",\n" +
                "        \"carTax\":\"420\",\n" +
                "        \"carStatus\":\"旧车\",\n" +
                "        \"carWorth\":\"A\",\n" +
                "\t\t\"sanzhebaoe\":\"10000\",\n" +
                "\t\t\"policyBizSource\":\"pc\"\n" +
                "    }\n" +
                "}\n";

//        rabbitTemplate.convertAndSend(exchange, routingKey1, testData);
//
//        rabbitTemplate.convertAndSend(exchange, routingKey2, testData);
//
//        rabbitTemplate.convertAndSend(exchange, routingKey3, testData);

//        rabbitTemplate.convertAndSend(exchange, routingKey4, testData);

        outMap.put("success", true);
        outMap.put("data", exchange + "; " + routingKey1);

        return JSON.toJSONString(outMap);
    }

    @GetMapping("/testGenPrepayId")
    public String testGenPrepayId(HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> outMap = new HashMap<String, Object>();
        outMap.put("success", false);

        String body = "平安短期境内旅游保险(经济型)";
        String out_trade_no = "15065919020500017196397";
        String total_fee = "300";
        String openid = "oFT0JwnnHzZeE-oRA25EHKHj99ZQ";

        String rtn = getPrepayId(body, out_trade_no, total_fee, openid);

        outMap.put("prepayId", rtn);
        outMap.put("success", true);

        return JSON.toJSONString(outMap);
    }


    /**
     * --------------------------------------------------------------------------------------------------
     */

    /**
     * 测试环境模拟支付成功使用
     * @param orderno
     * @return
     */
    @GetMapping("/testPay")
    public boolean testPay(String orderno){
        Map<String,String>  param = new HashMap<String, String>();
        param.put("orderno",orderno);
        param.put("flag","SUCCESS");

//        rabbitTemplate.convertAndSend(exchange, routingKey1, JSON.toJSONString(param));
//        rabbitTemplate.convertAndSend(exchange, routingKey2, JSON.toJSONString(param));
        return true;
    }


    /**
     * 获取二维码
     * @param body
     * @param orderNo
     * @param total_fee
     * @return
     */
     /*
    @GetMapping("/pay/qrcode")
    public ResponseEntity<RestResult> payQRCode(String body, String orderNo, String total_fee) {
//        String _qrcode_notify_url = "http://zjtest.yunbaox.com:7000/api/paymentservice/pay/public/qrcode/callBack";
        String _qrcode_notify_url = "http://zj.yunbaox.com:7000/api/paymentservice/pay/public/qrcode/callBack";
        String trade_type = "NATIVE";
        String code_url = getCodeUrl(body,orderNo,total_fee,trade_type,_qrcode_notify_url);
        System.out.println("qrcode_url == " + code_url);
        RestResult restResult = new RestResult(RestConst.SUCCESS, code_url);
        ResponseEntity<RestResult> responseEntity = new ResponseEntity<RestResult>(restResult, HttpStatus.OK);
        return responseEntity;
    }
    */

    /**
     * 统一下单
     * @param body
     * @param out_trade_no
     * @param total_fee
     * @param trade_type
     * @param notify_url
     * @return
     */
    private String getCodeUrl(String body, String out_trade_no, String total_fee,String trade_type,String notify_url) {
        String code_url = null;
        SortedMap<String, String> map = new TreeMap<String, String>();
        map.put("appid", _appId);
        map.put("mch_id", _mch_id);
        map.put("nonce_str", UUID.randomUUID().toString().replace("-", "").substring(0, 16));
        map.put("body", body);
        map.put("out_trade_no", out_trade_no);
        map.put("product_id", out_trade_no);
        map.put("total_fee", total_fee);
        map.put("spbill_create_ip", "127.0.0.1");
        map.put("notify_url", notify_url);
        map.put("trade_type", trade_type);
        String sign = WeChatUtil.sign(map, _payKey);//参数加密
        map.put("sign", sign);

        String xml = WeChatUtil.mapToXml(map);
        try {
            writeLog2Db(null, "统一下单, 请求", xml);

            String response = httpClient.postData("https://api.mch.weixin.qq.com/pay/unifiedorder", xml);

            writeLog2Db(null, "统一下单, 返回", response);

            Map<String, String> result = WeChatUtil.readStringXmlOut(response);
            if(result != null) {
                if ("SUCCESS".equals(result.get("return_code")) && !"FAIL".equals(result.get("result_code"))) {
                    code_url = result.get("code_url");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return code_url;
    }

    /**
     * 二维码支付记过回调
     * @param request
     * @param response
     */
    @PostMapping("/pay/public/qrcode/callBack")
    public String qrcodePayCallBack(HttpServletRequest request, HttpServletResponse response) {
        String returnXml = "";
        StringBuffer msgXml = new StringBuffer(600);
        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(request.getInputStream(), "utf-8"));
            String rtn = null;
            while ((rtn = br.readLine()) != null) {
                msgXml.append(rtn);
            }
            String xml = msgXml.toString();
            System.out.println(xml);

            writeLog2Db(null, "二维码支付回调, 返回", xml);

            if(StringUtils.isNotEmpty(xml)) {
                Map<String, String> result =  WeChatUtil.readStringXmlOut(xml);
                if("SUCCESS".equals(result.get("return_code"))){
                    Map<String,String>  param = new HashMap<String, String>();
                    param.put("orderno",result.get("out_trade_no").toString());
                    param.put("flag",result.get("result_code").toString());

//                    rabbitTemplate.convertAndSend(exchange, routingKey1, JSON.toJSONString(param));
//                    rabbitTemplate.convertAndSend(exchange, routingKey2, JSON.toJSONString(param));
//                    rabbitTemplate.convertAndSend(exchange, routingKey3, msgXml);

                    //异步回调接口
                    returnXml = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
//                    response.sendRedirect("http://zj.yunbaox.com:7000/#/baoyun/order/orderlist");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return returnXml;
    }
}
